#ifdef GL_ES
precision mediump float;
#endif

#extension GL_OES_standard_derivatives : enable

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

vec3 yellow = vec3(1.0, 1., 0.);
vec3 blue = vec3(0.0, 0., 1.);
float perFac = 1.7777777; // 16:9

vec3 yellow_stripe(vec2 pos){
	if(pos.y > -.06 && pos.y < .06){
		return yellow;
	}else {
		return blue;
	}
}

vec3 sweden_col(vec2 pos) {
	vec3 color;
	if( pos.x < (-.20)){
		return yellow_stripe(pos);
	} else if(pos.x < -.08) {
		return yellow;
	} else {
		return yellow_stripe(pos);
	}
	return color;
}

float circle_mix(vec2 pos) {
	float dist = length(pos) * sin(time * 2.) * 5.;
	dist *= sin(pos.x + (time * 2.));
	dist *= sin(pos.y + (time * cos(2.)));
	return exp(-(dist*dist)) * (cos(20.0*dist) + 1.0) / 2.0;
}

vec3 japan_col(vec2 pos){
	float r = 0.08;
	vec2 center = vec2(.0, .0);
	vec2 p = pos;
	p.x *= pos.x *= perFac;
	p.y *= pos.y *= perFac;
	vec3 color;
	if(pow((pos.x - center.x), 2.) + pow((pos.y - center.y), 2.) < r){
		return vec3(1.,0,0);
	} else {
		return vec3(1.);
	}
}

float fract_mix(vec2 p) {
	float c = 0.;
	p *= 2.;
	const int samples = 3000;
	for (int i = 0; i < samples; i++)
	{
		if (length(p*sin(time * 1.)) > 1.2)
			break;
		float x = p.x*p.x - p.y*p.y + (p.x - .7);
		p.y = 2. * p.x * p.y + (p.y - .6);
		p.x = x;
		c += 1./5.;	
	}
	
	return fract(c);
}

float mandelbrot_mix(vec2 pos) {
	pos *= 2.0 - (sin(time) * .2);
	pos.x += -.0;
	vec2 z = vec2(0.0,0.0);
	float c = 0.0;
	
	pos += sin(time + pos.x) * .3;
	pos += cos(time + pos.y) * .5;
	
	float r  = sin(time * 2.) + (time / 3.);
	mat2 rot = mat2(cos(r),sin(r),-sin(r),cos(r));
	pos *= rot;
	for(int i = 0; i < 128; ++i) {
		vec2 nz;
		nz.x = z.x * z.x - z.y * z.y + pos.x;
		nz.y = 2.0 * z.x * z.y + pos.y;
		z = nz;
		c = step(length(z), 2.0);
	}
	return c;
}

float under_wave(vec2 pos){
	return smoothstep(.5 + .5 * (sin(time + (pos.x * 5.)) + (pos.y * 4.)), .5, 5.);
}

float plasma_mix(vec2 pos) { 
	float t = time * .4;
	float color = sin((t * 4.) + pos.x * cos( t / 15.0 ) * 80.0 + t) + cos( pos.y * cos( t / 15.0 ) * 10.0 );
	color += sin(pos.y * sin( t / 10.0 ) * 40.0 ) + cos( pos.x * sin( t / 25.0 ) * 40.0 );
	color += sin( pos.x * sin( t / 5.0 ) * 10.0 ) + sin( pos.y * sin( t / 35.0 ) * 80.0 );
	return color;
}

int running_time = 0;
vec3 render_bg(vec2 pos) {
	running_time = int(mod(floor(time), 60.));
	
	if(running_time >= 0 && running_time < 30){
		return vec3(mix(japan_col(pos), sweden_col(pos), mix(plasma_mix(pos), mandelbrot_mix(pos), .5 + .5 *sin(time * .5))));
	} else if(running_time >= 30 && running_time <= 60){
		return vec3(mix(japan_col(pos), sweden_col(pos), mix(circle_mix(pos), fract_mix(pos), .5 + .5*sin(time * .5))));
	} else {
		return vec3(1.);
	}
}

void main( void ) {
	vec2 pos =  vec2(gl_FragCoord.x /resolution.x, gl_FragCoord.y /resolution.x) ;
	pos.x -= 0.5;
	pos.y -= resolution.y * 0.5/resolution.x;
	
	gl_FragColor  =  vec4(render_bg(pos), 1.);
}

